﻿using System;
using System.Globalization;
using System.IO;
using Styx.Common;
using Styx.CommonBot;
using Styx.WoWInternals;

namespace HBTracker
{
    class TrackerEvents
    {
        private static readonly CultureInfo MyCulture = CultureInfo.InvariantCulture;
        private static readonly string MyWowLocation = Styx.StyxWoW.Memory.Process.MainModule.FileName.Substring(0, Styx.StyxWoW.Memory.Process.MainModule.FileName.Length - 8);

        public static void GbankUpdate(object sender, LuaEventArgs args) { HBTracker.Data["gbankmoney"] = Convert.ToUInt32(Lua.GetReturnVal<Int32>("return GetGuildBankMoney()", 0)).ToString(MyCulture); }

        #region Global Event Region

        public static void AttachEvents()
        {
            BotEvents.OnBotStopped += OnStop;
            BotEvents.OnBotStarted += OnStart;

            BotEvents.Player.OnPlayerDied += OnDead;
            BotEvents.Player.OnLevelUp += OnLevel;

            Lua.Events.AttachEvent("CHAT_MSG_WHISPER", Whisper);
            Lua.Events.AttachEvent("CHAT_MSG_BN_WHISPER", BnetWhisper);

            Lua.Events.AttachEvent("GUILDBANKFRAME_OPENED", GbankUpdate);
            Lua.Events.AttachEvent("GUILDBANK_UPDATE_MONEY", GbankUpdate);

            Lua.Events.AttachEvent("GUILD_INVITE_REQUEST", GotInvitedToGuild);
        }

        public static void DetachEvents()
        {
            BotEvents.OnBotStopped -= OnStop;
            BotEvents.OnBotStarted -= OnStart;

            BotEvents.Player.OnPlayerDied -= OnDead;
            BotEvents.Player.OnLevelUp -= OnLevel;

            Lua.Events.DetachEvent("CHAT_MSG_WHISPER", Whisper);
            Lua.Events.DetachEvent("CHAT_MSG_BN_WHISPER", BnetWhisper);

            Lua.Events.DetachEvent("GUILDBANKFRAME_OPENED", GbankUpdate);
            Lua.Events.DetachEvent("GUILDBANK_UPDATE_MONEY", GbankUpdate);

            Lua.Events.DetachEvent("GUILD_INVITE_REQUEST", GotInvitedToGuild);
        }

        #endregion

        #region Screenshot Thingy

        public static void TakeScreen()
        {
            Logging.Write("[HBTracker] Screenshot requested");
            Lua.Events.AttachEvent("SCREENSHOT_SUCCEEDED", UploadScreenAndDeleteLocally);
            Lua.DoString("TakeScreenshot()");
        }

        private static void UploadScreenAndDeleteLocally(object sender, LuaEventArgs args)
        {
            Lua.Events.DetachEvent("SCREENSHOT_SUCCEEDED", UploadScreenAndDeleteLocally);
            var directory = new DirectoryInfo(MyWowLocation + "\\Screenshots\\");
            string ret = "";
            string myLastScreenShotTaken = directory + Util.GetLatestWritenFileFileInDirectory(directory).ToString();
            if (HBTrackerSettings.Instance.ScriptUrl.Length > 15)
                ret = Util.PostToFtp(myLastScreenShotTaken);

            HBTracker.Data["screen"] = ret;
            Logging.Write("[HBTracker] Screenshot sent");

            //Delete the screen, no need to keep them locally.
            File.Delete(myLastScreenShotTaken);

            HBTracker.Send(HBTracker.Data);
        }

        #endregion

        #region Chat Events

        //CHAT FLOOD PREVENT
        public static string LastMessage;

        public static void Whisper(object sender, LuaEventArgs args)
        {
            var myMessage = args.Args[0].ToString();
            var myAuthor = args.Args[1].ToString();

            if (myAuthor == Styx.StyxWoW.Me.Name || myMessage == LastMessage)
                return;

            if (HBTrackerSettings.Instance.NotfWhisp)
            {
                Logging.Write("[HBTracker] New Whisper (From: {0}) sending notification with the following message -> {1}", myAuthor, myMessage);
                Util.SendToProwl(string.Format("Whisper to {0}!", Styx.StyxWoW.Me.Name), string.Format("From: [{0}] \r\nMessage: {1}", myAuthor, myMessage));
                LastMessage = myMessage;
            }
        }

        public static void BnetWhisper(object sender, LuaEventArgs args)
        {
            // Somehow, Full name is returned as a Kstring unescaped, useless so.
            var Args = args.Args;
            var myMessage = Args[0].ToString();
            var PresenceId = Args[12].ToString();
            var myAuthorInfo = Lua.GetReturnValues(string.Format("return BNGetFriendInfo(BNGetFriendIndex({0}))", PresenceId));
            var myAuthorBTAG = myAuthorInfo[2];
            var myAuthorToon = myAuthorInfo[4];

            if (HBTrackerSettings.Instance.Pdebug)
            {
                Logging.Write("[HBTracker] myMessage -> " + myMessage);
                Logging.Write("[HBTracker] PresenceId -> " + PresenceId);
                Logging.Write("[HBTracker] myAuthorBTAG -> " + myAuthorBTAG);
                Logging.Write("[HBTracker] myAuthorToon (local) -> " + myAuthorToon);
                myAuthorInfo.ForEach(info => Logging.Write("[HBTracker] myMessage -> " + info));
            }

            if (myMessage == LastMessage)
                return;

            if (HBTrackerSettings.Instance.NotfBnetWhisper)
            {
                Logging.Write("[HBTracker] New BNET Whisper (From: {0} ({1}) sending notification with the following message -> {2}", myAuthorBTAG, myAuthorToon, myMessage);
                Util.SendToProwl(string.Format("Battle.NET Whisper to {0}!", Styx.StyxWoW.Me.Name), string.Format("From {0} ({1}) \r\nMessage: {2}", myAuthorBTAG, myAuthorToon, myMessage));
                LastMessage = myMessage;
            }
        }

        #endregion

        #region Guild Events

        public static void GotInvitedToGuild(object sender, LuaEventArgs args)
        {
            //var inviteAuthor = args.Args[0].ToString(); Useless for the moment, maybe later.
            var guildName = args.Args[1].ToString();
            var currentGuildLevel = Convert.ToUInt32(args.Args[2]);

            if (currentGuildLevel >= 25)
            {
                Logging.Write("[HBTracker] {0} is a guild is level 25 ! let's get into this.", guildName);
                Lua.DoString("AcceptGuild()");
                Lua.DoString("StaticPopup_Hide(\"GUILD_INVITE_REQUEST\")");
                Lua.Events.DetachEvent("GUILD_INVITE_REQUEST", GotInvitedToGuild);
            }

        }

        #endregion

        #region onX

        public static DateTime StartTime;

        public static void OnStart(EventArgs args)
        {

            StartTime = DateTime.Now;
            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] OnStart event called");

            HBTracker.Data["name"] = Styx.StyxWoW.Me.Name;
            HBTracker.Data["server"] = Styx.StyxWoW.Me.RealmName;

            if (HBTrackerSettings.Instance.NotfStart)
                Util.SendToProwl("Bot Started!", "(" + HBTracker.Data["level"] + ") " + HBTracker.Data["server"] + " - " + HBTracker.Data["name"] + "'s bot started.");

            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] OnStart event finished");

        }

        public static void OnStop(EventArgs args)
        {

            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] OnStop event called");

            if (HBTrackerSettings.Instance.NotfStop)
                Util.SendToProwl("Bot Stopped!", "(" + HBTracker.Data["level"] + ") " + HBTracker.Data["server"] + " - " + HBTracker.Data["name"] + "'s bot has been stopped.");

            if (HBTrackerSettings.Instance.Pdebug) Logging.Write("[HBTracker] OnStop event finished");

        }

        public static void OnDead()
        {
            using (Styx.StyxWoW.Memory.AcquireFrame())
            {
                HBTracker.Data["death"] = Convert.ToInt32(GameStats.Deaths).ToString(MyCulture);
                HBTracker.Data["deathh"] = Convert.ToInt32(GameStats.DeathsPerHour).ToString(MyCulture);
            }

            if (HBTrackerSettings.Instance.NotfDied)
                Util.SendToProwl("Death!", "(" + HBTracker.Data["level"] + ") " + HBTracker.Data["server"] + " - " + HBTracker.Data["name"] + " died.");
        }

        public static void OnLevel(BotEvents.Player.LevelUpEventArgs args)
        {

            HBTracker.Data["level"] = Convert.ToInt32(Styx.StyxWoW.Me.Level).ToString(MyCulture);

            if (HBTrackerSettings.Instance.NotfLevel)
                Util.SendToProwl("Level Up!", HBTracker.Data["server"] + " - " + HBTracker.Data["name"] + " has reached level " + HBTracker.Data["level"] + ".");

        }

        #endregion

    }
}
